﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace HKQuery.Common
{
    public enum CheckGetEnum
    {
        Int = 0,
        Safety = 1,
        Decimal = 2
    }
    public class RegExp
    {
        #region 判断是否为Unicode码 public static bool IsUnicode(string s)
        /// <summary>
        /// 判断是否为Unicode码
        /// </summary>
        public static bool IsUnicode(string s)
        {
            string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 得到二个正整数的分数值 	public static string[] GetPercence(int a, int b)
        /// <summary>
        /// 得到二个正整数的分数值
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static string[] GetPercence(int a, int b)
        {
            while (true)
            {
                if (0 == a % 2 && 0 == b % 2)
                {
                    a = a / 2;
                    b = b / 2;
                }
                else if (0 == a % 3 && 0 == b % 3)
                {
                    a = a / 3;
                    b = b / 3;
                }
                else if (0 == a % 5 && 0 == b % 5)
                {
                    a = a / 5;
                    b = b / 5;
                }
                else if (0 == a % 7 && 0 == b % 7)
                {
                    a = a / 7;
                    b = b / 7;
                }
                else
                {
                    break;
                }
            }
            return new string[2] { a.ToString(), b.ToString() };
        }
        #endregion

        #region 二个时间差了多少天,多少小时的计算 public static string[] GetDifDateAndTime(object todate, object fodate)
        /// <summary>
        /// 二个时间差了多少天,多少小时的计算 
        /// </summary>
        /// <param name="todate"></param>
        /// <param name="fodate"></param>
        /// <returns></returns>
        public static string[] GetDifDateAndTime(object todate, object fodate)
        {
            string[] DateHoure = new string[2];

            System.TimeSpan ts = System.DateTime.Parse(todate.ToString()) - System.DateTime.Parse(fodate.ToString());

            double alltimes = ts.TotalSeconds;
            alltimes = alltimes / (60 * 60 * 24);
            string strdate = alltimes.ToString();
            int length = alltimes.ToString().Length;
            int start = alltimes.ToString().LastIndexOf(@".");
            int date = (int)System.Math.Round(alltimes, 10);
            int houre = (int)(double.Parse("0" + alltimes.ToString().Substring(start, length - start)) * 24);
            DateHoure[0] = date.ToString();
            DateHoure[1] = houre.ToString();
            return DateHoure;
        }
        #endregion

        #region 二个时间差了多少天,多少小时的计算 public static string GetDifDateAndTime(object todate, object fodate, string v1, string v2, string v3, string v4, string v5, string v6)
        /// <summary>
        /// 二个时间差了多少天,多少小时的计算
        /// </summary>
        /// <param name="todate"></param>
        /// <param name="fodate"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetDifDateAndTime(object todate, object fodate, string v1, string v2, string v3, string v4, string v5, string v6)
        {
            System.TimeSpan ts = System.DateTime.Parse(todate.ToString()) - System.DateTime.Parse(fodate.ToString());

            int y = (int)ts.TotalDays / 365;

            int M = (int)((ts.TotalDays / 365 - (double)(int)(ts.TotalDays / 365)) * 12);

            int d = ts.Days - y * 365 - M * 30;

            int h = ts.Hours;

            int m = ts.Minutes;
            string rsr = "";

            if (0 != y)
            {
                rsr += y.ToString() + v1;
            }
            if (0 != M)
            {
                rsr += M.ToString() + v2;
            }
            if (0 != d)
            {
                rsr += d.ToString() + v3;
            }
            if (0 != h)
            {
                rsr += h.ToString() + v4;
            }
            if (0 != m)
            {
                rsr += m.ToString() + v5;
            }
            if (0 == y && 0 == M && 0 == d && 0 == h && 0 == m)
            {
                return v6;
            }
            return rsr;
        }
        #endregion

        #region 判断字符串是否由数字组成
        /// <summary>
        /// 判断字符串是否由数字组成
        /// </summary>
        public static bool IsNumeric(string s)
        {
            string pattern = @"^\-?[0-9]+$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断字符串是否由汉字组成 public static bool isChinese(string s)
        /// <summary>
        /// 判断字符串是否由汉字组成
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool isChinese(string s)
        {
            string pattern = @"^[\u4e00-\u9fa5]{2,}$";

            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断是否是正整数 public static bool IsUnsNumeric(string s)
        /// <summary>
        /// 判断是否是正整数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsUnsNumeric(string s)
        {
            string pattern = @"^[0-9]+$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断表名是否符合要求，只能是**_bbs+整数数字的格式。 public static bool IsTable(string s)
        ///// <summary>
        ///// 判断表名是否符合要求，只能是**_bbs+整数数字的格式。
        ///// </summary>
        ///// <param name="s"></param>
        ///// <returns></returns>
        //public static bool IsTable(string s)
        //{
        //    string TablePrefix = Fetch.TablePrefix + "bbs";
        //    string pattern = @"^" + TablePrefix + "[1-9]{1}$";
        //    return Regex.IsMatch(s, pattern);
        //}
        #endregion

        #region 判断是否是正整数 public static bool IsUnsFlaot(string s)
        /// <summary>
        /// 判断是否是正整数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsUnsFlaot(string s)
        {
            string pattern = @"^[0-9]+.?[0-9]+$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region  判断字符串是否是正确的 IP 地址格式 public static bool IsIp(string s)
        /// <summary> 
        /// 判断字符串是否是正确的 IP 地址格式
        /// </summary>
        public static bool IsIp(string s)
        {
            string pattern = @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断字符串是否存在操作数据库的安全隐患 public static bool IsSafety(string s)
        /// <summary>
        /// 判断字符串是否存在操作数据库的安全隐患
        /// </summary>
        public static bool IsSafety(string s)
        {
            string str = s.Replace("%20", " ");
            str = Regex.Replace(str, @"\s", " ");
            string pattern = @"select |insert |delete from |count\(|drop table|update |truncate |asc\(|mid\(|char\(|xp_cmdshell|exec master|net localgroup administrators|:|net user|""|\'| or ";
            return !Regex.IsMatch(str, pattern, RegexOptions.IgnoreCase);
        }
        #endregion

        #region 判断字符串是否是正确的 Url 地址格式 public static bool IsUrl(string s)

        /// <summary>
        /// 判断字符串是否是正确的 Url 地址格式
        /// </summary>
        public static bool IsUrl(string s)
        {
            string pattern = @"^(http|https|ftp|rtsp|mms):(\/\/|\\\\)[A-Za-z0-9%\-_@]+\.[A-Za-z0-9%\-_@]+[A-Za-z0-9\.\/=\?%\-&_~`@:\+!;]*$";
            return Regex.IsMatch(s, pattern, RegexOptions.IgnoreCase);
        }
        #endregion

        #region 判断是否为相对地址（虚拟地址） public static bool IsRelativePath(string s)
        /// <summary>
        /// 判断是否为相对地址（虚拟地址）
        /// </summary>
        public static bool IsRelativePath(string s)
        {
            if (s == null || s == string.Empty)
            {
                return false;
            }
            if (s.StartsWith("/") || s.StartsWith("?"))
            {
                return false;
            }
            if (Regex.IsMatch(s, @"^\s*[a-zA-Z]{1,10}:.*$"))
            {
                return false;
            }
            return true;
        }
        #endregion

        #region 判断是否为绝对地址（物理地址） 	public static bool IsPhysicalPath(string s)
        /// <summary>
        /// 判断是否为绝对地址（物理地址）
        /// </summary>
        public static bool IsPhysicalPath(string s)
        {
            string pattern = @"^\s*[a-zA-Z]:.*$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断是否为正确的 email 地址格式 public static bool IsEmail(string s)
        /// <summary>
        /// 判断是否为正确的 email 地址格式
        /// </summary>
        public static bool IsEmail(string s)
        {
            string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion

        #region 判断字符串是否是整数或小数
        /// <summary>
        /// 判断字符串是否是整数或小数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool isDecimal(string s)
        {
            string pattern = @"^[+-]?\d+(\.\d+)?$";
            return Regex.IsMatch(s, pattern);
        }
        #endregion
    }
    public class Fetch
    {

        #region Fields
        //private static readonly string mTablePrefix;
        public static readonly string SiteMapPath;
        #endregion

        #region 构造函数,初始化变量前缀等。
        static Fetch()
        {

        }
        #endregion

        #region 获取页面提交的参数值，相当于 Request.Form public static string Post(string name)
        /// <summary>
        /// 获取页面提交的参数值，相当于 Request.Form
        /// </summary>
        public static string Post(string name)
        {
            string value = HttpContext.Current.Request.Form[name];
            return value == null ? string.Empty : value;
        }
        #endregion

        #region 获取页面地址的参数值，相当于 Request.QueryString public static string Get(string name)
        /// <summary>
        /// 获取页面地址的参数值，相当于 Request.QueryString
        /// </summary>
        public static string Get(string name)
        {
            string value = HttpContext.Current.Request.QueryString[name];
            return value == null ? string.Empty : value.Trim();
        }
        #endregion

        #region 获取页面地址的参数值并检查安全性，相当于 Request.QueryString public static string Get(string name, CheckGetEnum chkType)
        /// <summary>
        /// 获取页面地址的参数值并检查安全性，相当于 Request.QueryString
        /// chkType 有 CheckGetEnum.Int， CheckGetEnum.Safety两种类型，
        /// CheckGetEnum.Int 保证参数是数字型
        /// CheckGetEnum.Safety 保证提交的参数值没有操作数据库的语句
        /// </summary>
     
        #region 判断输入的字符串是否安全
        /// <summary>
        /// 判断输入的内容是否安全
        /// </summary>
        /// <param name="value"></param>
        /// <param name="chkType"></param>
        /// <returns></returns>
        public static string InspectData(string value, CheckGetEnum chkType)
        {
            bool isPass = false;
            switch (chkType)
            {
                default:
                    isPass = true;
                    break;
                case CheckGetEnum.Int:
                    {
                        try
                        {
                            int.Parse(value);
                            isPass = RegExp.IsNumeric(value);
                        }
                        catch
                        {
                            isPass = false;
                        }
                        break;
                    }
                case CheckGetEnum.Safety:
                    isPass = RegExp.IsSafety(value);
                    break;
                case CheckGetEnum.Decimal:
                    {
                        try
                        {
                            decimal.Parse(value);
                            isPass = RegExp.IsNumeric(value);
                        }
                        catch
                        {
                            isPass = false;
                        }
                        break;
                    }
            }
            if (!isPass)
            {
                //new Terminator().Throw("地址栏中参数“" + name + "”的值不符合要求或具有潜在威胁，请不要手动修改URL。");
                return string.Empty;
            }
            return value;
        }
        #endregion

        #region 跟踪调试输出一个对象 public static void  Trace(object obj)
        /// <summary>
        /// 跟踪调试输出一个对象
        /// </summary>
        public static void Trace(object obj)
        {
            HttpContext.Current.Response.Write(obj.ToString());
        }
        #endregion



        #region IP 地址字符串形式转换成长整型 public static long Ip2Int(string ip)
        /// <summary>
        /// IP 地址字符串形式转换成长整型
        /// </summary>
        public static long Ip2Int(string ip)
        {
            if (!RegExp.IsIp(ip))
            {
                return -1;
            }
            string[] arr = ip.Split('.');
            long lng = long.Parse(arr[0]) * 16777216;
            lng += int.Parse(arr[1]) * 65536;
            lng += int.Parse(arr[2]) * 256;
            lng += int.Parse(arr[3]);
            return lng;
        }
        #endregion

        #region 获取客户端IP  public static string UserIp
        /// <summary>
        /// 获取客户端IP 
        /// </summary>
        public static string UserIp
        {
            get
            {
                string ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (ip == null || ip == string.Empty)
                {
                    ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }
                if (!RegExp.IsIp(ip))
                {
                    return "Unknown";
                }
                return ip;
            }
        }
        #endregion

        #region  获取访问者所使用的浏览器名 public static string UserBrowser
        /// <summary>
        /// 获取访问者所使用的浏览器名
        /// </summary>
        public static string UserBrowser
        {
            get
            {
                string agent = HttpContext.Current.Request.UserAgent;
                if (agent == null || agent == string.Empty)
                    return "Unknown";
                agent = agent.ToLower();

                HttpBrowserCapabilities bc = HttpContext.Current.Request.Browser;
                if (agent.IndexOf("firefox") >= 0
                    || agent.IndexOf("firebird") >= 0
                    || agent.IndexOf("myie") >= 0
                    || agent.IndexOf("opera") >= 0
                    || agent.IndexOf("netscape") >= 0
                    || agent.IndexOf("msie") >= 0
                    )
                    return bc.Browser + bc.Version;

                return "Unknown";
            }
        }
        #endregion

        #region 获得网站域名 	public static string ServerDomain
        /// <summary>
        /// 获得网站域名
        /// </summary>
        public static string ServerDomain
        {
            get
            {
                string host = HttpContext.Current.Request.Url.Host.ToLower();
                string[] arr = host.Split('.');
                if (arr.Length < 3 || RegExp.IsIp(host))
                {
                    return host;
                }
                string domain = host.Remove(0, host.IndexOf(".") + 1);
                if (domain.StartsWith("com.") || domain.StartsWith("net.") || domain.StartsWith("org.") || domain.StartsWith("gov."))
                {
                    return host;
                }
                return domain;
            }
        }
        #endregion

        #region 获得当前路径
        /// <summary>
        /// 获得当前路径
        /// </summary>
        public static string CurrentPath
        {
            get
            {
                string path = HttpContext.Current.Request.Path;
                path = path.Substring(0, path.LastIndexOf("/"));
                if (path == "/")
                {
                    return string.Empty;
                }
                return path;
            }
        }
        #endregion



        #region 获得当前URL public static string CurrentUrl
        /// <summary> 
        /// 获得当前URL
        /// </summary>
        public static string CurrentUrl
        {
            get
            {
                return HttpContext.Current.Request.Url.ToString();
            }
        }
        #endregion

        #region 获取当前请求的原始URL
        /// <summary>
        /// 获取当前请求的原始 URL
        /// </summary>
        public static string webCurrentUrl
        {
            get
            {
                return HttpContext.Current.Request.RawUrl.ToString();
            }
        }
        #endregion

        #region 获得来源URL public static string Referrer
        /// <summary>
        /// 获得来源URL
        /// </summary>
        public static string Referrer
        {
            get
            {
                Uri uri = HttpContext.Current.Request.UrlReferrer;
                if (uri == null)
                {
                    return string.Empty;
                }
                return Convert.ToString(uri);
            }
        }
        #endregion

        #region 是否从其他连接向本域名连接 	public static bool IsPostFromAnotherDomain
        /// <summary>
        /// 是否从其他连接向本域名连接
        /// </summary>
        public static bool IsPostFromAnotherDomain
        {
            get
            {
                if (HttpContext.Current.Request.HttpMethod == "GET")
                {
                    return false;
                }
                return Referrer.IndexOf(ServerDomain) == -1;
            }
        }
        #endregion

        #region 是否从其他连接向本域名以POST方式提交表单 	public static bool IsGetFromAnotherDomain
        /// <summary>
        /// 是否从其他连接向本域名以POST方式提交表单
        /// </summary>
        public static bool IsGetFromAnotherDomain
        {
            get
            {
                if (HttpContext.Current.Request.HttpMethod == "POST")
                {
                    return false;
                }
                return Referrer.IndexOf(ServerDomain) == -1;
            }
        }
        #endregion

        #region 是否被判断为机器人 public static bool IsRobots
        /// <summary>
        /// 是否被判断为机器人 
        /// </summary>
        public static bool IsRobots
        {
            get
            {
                return IsWebSearch();
            }
        }
        #endregion

        #region 搜索引擎来源判断 public static bool IsWebSearch()

        /// <summary>
        /// 搜索引擎来源判断
        /// </summary>
        private static string[] _WebSearchList = new string[] { "google", "isaac", "surveybot", "baiduspider", "yahoo", "yisou", "3721", "qihoo", "daqi", "ia_archiver", "p.arthur", "fast-webcrawler", "java", "microsoft-atl-native", "turnitinbot", "webgather", "sleipnir", "msn" };
        public static bool IsWebSearch()
        {
            string user_agent = HttpContext.Current.Request.UserAgent;
            if (null == user_agent || string.Empty == user_agent)
            {
                return true;
            }
            else
            {
                user_agent = user_agent.ToLower();
            }

            for (int i = 0; i < _WebSearchList.Length; i++)
            {
                if (-1 != user_agent.IndexOf(_WebSearchList[i]))
                {
                    return true;
                }
            }
            return UserBrowser.Equals("Unknown");
        }
        #endregion

        #region Url编码，相当于 Server.UrlEncode public static string UrlEncode(string url)
        /// <summary>
        /// Url编码，相当于 Server.UrlEncode
        /// </summary>
        public static string UrlEncode(string url)
        {
            return HttpContext.Current.Server.UrlEncode(url);
        }
        #endregion

        #region 属性
        /// <summary>
        /// 变量前缀
        /// </summary>
        //public static string TablePrefix
        //{
        //    get
        //    {
        //        return mTablePrefix;
        //    }
        //}



        #endregion


        #region 判断字符串是否有非法的字符
        /// <summary>
        /// 判断字符串是否有非法的字符
        /// </summary>
        /// <param name="value"></param>
        /// <param name="chkType"></param>
        /// <returns></returns>
        public static string estimateString(string value, CheckGetEnum chkType)
        {
            bool isPass = false;
            switch (chkType)
            {
                default:
                    isPass = true;
                    break;
                case CheckGetEnum.Int:
                    {
                        try
                        {
                            int.Parse(value);
                            isPass = RegExp.IsNumeric(value);
                        }
                        catch
                        {
                            isPass = false;
                        }
                        break;
                    }
                case CheckGetEnum.Decimal:
                    {
                        try
                        {
                            decimal.Parse(value);
                            isPass = RegExp.isDecimal(value);
                        }
                        catch
                        {
                            isPass = false;
                        }
                        break;
                    }
                case CheckGetEnum.Safety:
                    isPass = RegExp.IsSafety(value);
                    break;
            }
            if (!isPass)
            {
                //new Terminator().Throw("参数值不符合要求或具有潜在威胁，请不要手动修改URL。");
                return string.Empty;
            }
            return value;
        }

        #endregion

        /// <summary>
        /// 检测用户ip是否在指定的ip段中
        /// </summary>
        /// <param name="ip">用户ip</param>
        /// <param name="begip">起始ip</param>
        /// <param name="endip">结束ip</param>
        /// <returns></returns>
        public static bool isinip(string ip, string begip, string endip)
        {
            int[] inip, begipint, endipint = new int[4];
            inip = getIp(ip);
            begipint = getIp(begip);
            endipint = getIp(endip);
            for (int i = 0; i < 4; i++)
            {
                if (inip[i] < begipint[i] || inip[i] > endipint[i])
                {
                    return false;
                }
                else if (inip[i] > begipint[i] || inip[i] < endipint[i])
                {
                    return true;
                }
            }
            return true;
        }
        /// <summary>
        /// 将ip地址转成整形数组
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        private static int[] getIp(string ip)
        {
            int[] retip = new int[4];
            int i, count;
            char c;
            for (i = 0, count = 0; i < ip.Length; i++)
            {
                c = ip[i];
                if (c != '.')
                {
                    retip[count] = retip[count] * 10 + int.Parse(c.ToString());
                }
                else
                {
                    count++;
                }
            }

            return retip;

        }

        #region 根据编号检索selectListItem里的值
        /// <summary>
        /// 根据编号获取值
        /// </summary>
        /// <param name="ListItem"></param>
        /// <param name="oldNo"></param>
        /// <returns></returns>
        public static string GetNameByNo(List<SelectListItem> ListItem, string oldNo)
        {
            string obj = null;
            var q = from c in ListItem
                    where c.Value == oldNo
                    select c.Text;
            if (q.Count() > 0)
            {
                obj = q.FirstOrDefault();
            }
            return obj;
        }

        #endregion

#endregion

    }
}